package com.jinzhi.jzweb.service.moduleConfig.impl;

import com.alibaba.excel.EasyExcel;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.plugins.Page;
import com.jinzhi.common.utils.Result;
import com.jinzhi.jzweb.domain.ExaminationBatchComSDO;
import com.jinzhi.jzweb.domain.ExaminationBatchDO;
import com.jinzhi.jzweb.domain.StuSignUpComDO;
import com.jinzhi.jzweb.pojo.ModuleConfig.LotteryManagementDto;
import com.jinzhi.jzweb.service.ExaminationBatchComSService;
import com.jinzhi.jzweb.service.ExaminationBatchService;
import com.jinzhi.jzweb.service.StuSignUpComService;
import com.jinzhi.jzweb.service.moduleConfig.LotteryManagementService;
import com.jinzhi.jzweb.utils.CustomerDailyImportListener;
import com.jinzhi.jzweb.utils.StringConverter;
import com.jinzhi.sys.domain.UserDO;
import com.jinzhi.sys.service.UserService;
import org.apache.commons.lang.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.stream.Collectors;

/*
 *  @author : JingChangTian
 *  @date   : 2023/9/28 9:56
 *  @description :
 *
 */
@Service
public class LotteryManagementServicelmpl implements LotteryManagementService {

    private final StuSignUpComService stuSignUpComService;

    private final ExaminationBatchComSService examinationBatchComSService;

    private final ExaminationBatchService examinationBatchService;

    private final UserService userService;

    public LotteryManagementServicelmpl(StuSignUpComService stuSignUpComService, ExaminationBatchComSService examinationBatchComSService, ExaminationBatchService examinationBatchService, UserService userService) {
        this.stuSignUpComService = stuSignUpComService;
        this.examinationBatchComSService = examinationBatchComSService;
        this.examinationBatchService = examinationBatchService;
        this.userService = userService;
    }

    @Override
    public Result<Object> lotteryBinding(MultipartFile file, Long cbatchId) {
        List<LotteryManagementDto> lottery = new ArrayList<>();
        if (!"application/vnd.ms-excel".equals(file.getContentType())) {
            return Result.fail("文件格式错误，请选择.xls文件");
        }
        try{
            InputStream inputStream = file.getInputStream();
            lottery = EasyExcel.read(inputStream)
                    // 这个转换是成全局的， 所有java为string,excel为string的都会用这个转换器。
                    // 如果就想单个字段使用请使用@ExcelProperty 指定converter
                    .registerConverter(new StringConverter())
                    // 注册监听器，可以在这里校验字段
                    .registerReadListener(new CustomerDailyImportListener())
                    .head(LotteryManagementDto.class)
                    .sheet()
                    .headRowNumber(2)
                    .doReadSync();
        } catch (Exception e) {
            e.getMessage();
            e.printStackTrace();
            return Result.fail(e.getMessage());
        }
        if(lottery.isEmpty()){
            return Result.fail("Excel数据为空，请检查");
        }
        //查询竞赛下场次
        ExaminationBatchDO exam  = new ExaminationBatchDO();
        exam.setCbatchId(cbatchId);
        exam.setType(4);
        ExaminationBatchDO examinationBatchDO = examinationBatchService.selectOne(exam);
        if(examinationBatchDO==null){
            return Result.fail("没有竞赛场次");
        }
        List<ExaminationBatchComSDO> examinationBatchComSDOS = examinationBatchComSService.selectList(
                new EntityWrapper<ExaminationBatchComSDO>().eq("pid",examinationBatchDO.getId()));
        if(examinationBatchComSDOS.isEmpty()){
            return Result.fail("没有赛道信息");
        }
        //查询竞赛下考生
        List<StuSignUpComDO> stus = stuSignUpComService.selectList(
                new EntityWrapper<StuSignUpComDO>().eq("cbatch_id",cbatchId));
        if(stus.isEmpty()){
            return Result.fail("没有录入考生信息");
        }


        //匹配赛场id
        lottery.forEach(a ->examinationBatchComSDOS.forEach(b ->{
            if(a.getCourt2().contains(b.getName())){
                a.setExId(b.getId());
            }
        }));

        //验证赛场
        for (int i = 0; i < lottery.size(); i++) {
            if(Objects.isNull(lottery.get(i).getExId())){
                return Result.fail("第"+(i+1)+"行"+lottery.get(i).getCourt2()+"赛道信息不存在");
            }
        }

        //根据考生信息匹配赛道
        lottery.forEach(a ->stus.forEach(b ->{
            if(StringUtils.isBlank(b.getTeacher()) || StringUtils.isBlank(b.getUnitName())){
                //考生数据领队或者院校为空跳出当前验证
            }else{
                if(Objects.equals(a.getTeacher().trim(),b.getTeacher()) && Objects.equals(a.getUnitName().trim(),b.getUnitName())){
                    //考生领队数据院校全部通过赋值赛场id
                    if(Objects.nonNull(a.getExId())){
                        b.setCourt2(a.getExId().toString());
                        a.setStuId(b.getId());
                    }
                }
            }
        }));

        //修改实操赛场不等于null或者不等""的考生信息
        List<StuSignUpComDO>  sign = stus.stream().filter(a -> StringUtils.isNotBlank(a.getCourt2())).collect(Collectors.toList());
        if(!sign.isEmpty()){
            stuSignUpComService.insertOrUpdateBatch(sign);
        }
        //返回没有匹配到的考生数据
        List<LotteryManagementDto>  noSign = lottery.stream().filter(a -> Objects.isNull(a.getStuId())).collect(Collectors.toList());
        return Result.ok(noSign);
    }

    @Override
    public Result<Object> getLotterySign(Integer current , Integer number) {
        Page<ExaminationBatchDO> page = new Page<ExaminationBatchDO>(current,number);
        //查询所有批次信息
        Page<ExaminationBatchDO> exams = examinationBatchService.selectPage(page,new EntityWrapper<ExaminationBatchDO>()
                .eq("type",3));
        //根据批次查询所有选手信息
        List<StuSignUpComDO> stuSigns = stuSignUpComService.selectList(new EntityWrapper<StuSignUpComDO>()
                .isNotNull("court2").ne("court2",""));
        if(exams.getRecords().isEmpty()){
            return Result.ok(exams);
        }
        if(stuSigns.isEmpty()){
            return Result.ok(exams);
        }
        //查询实操赛场名称
        List<String> court2s = Optional.of(stuSigns.stream().map(StuSignUpComDO::getCourt2).distinct().collect(Collectors.toList())).orElse(new ArrayList<>());
        List<ExaminationBatchComSDO> examSdos = examinationBatchComSService.selectList(new EntityWrapper<ExaminationBatchComSDO>().in("id",court2s));
        stuSigns.forEach(a -> examSdos.forEach(b ->{
            if(Objects.equals(a.getCourt2(),b.getId().toString())){
                a.setCourt2(b.getName());
            }
        }));

        //查询审核人信息
        List<Long> userIds = Optional.of(exams.getRecords().stream().map(ExaminationBatchDO::getCheckerId).
                filter(Objects::nonNull).distinct().collect(Collectors.toList())).orElse(new ArrayList<>());
        List<UserDO> userDOS = userService.selectList(new EntityWrapper<UserDO>().in("id",userIds));
        exams.getRecords().forEach(a -> userDOS.forEach(b ->{
            if(Objects.equals(a.getCheckerId(),b.getId())){
                a.setCbatchName(b.getName());
            }
        }));

        //绑定考生
        exams.getRecords().forEach(a -> stuSigns.forEach(b ->{
            if(Objects.equals(a.getId(),b.getCbatchId())){
                a.setSign(Optional.ofNullable(a.getSign()).orElse(new ArrayList<>()));
                a.getSign().add(b);
            }
        }));
        return Result.ok(exams);
    }

    @Override
    public Result<Object> updateSign(Long cbatchId) {
        List<StuSignUpComDO> stuSigns = stuSignUpComService.selectList(new EntityWrapper<StuSignUpComDO>()
                .isNotNull("court2")
                .eq("cbatch_id",cbatchId));
        stuSigns.forEach(a ->{
            a.setCourt2("");
            a.setLots(0);
        });
        if(!stuSigns.isEmpty()){
            //stuSignUpComService.deleteBatchIds(stuSigns);
            stuSignUpComService.insertOrUpdateBatch(stuSigns);
        }
        return Result.ok();
    }
}
